import urllib
import urllib2
import pprint
import simplejson

_debug = 1


class ChimpyException(Exception):
    pass


class Connection(object):
    """mailchimp api connection"""
    
    url = "http://api.mailchimp.com/1.1/"
    output = "json"
    
    def __init__(self, apikey=None):
        self._apikey = apikey
    
    def _rpc(self, **params):
        """make an rpc call to the server"""
        
        params = urllib.urlencode(params)
        
        if _debug > 1:
            print __name__, "making request with parameters"
            pprint.pprint(params)
            print __name__, "encoded parameters:", params
            
        
        response = urllib2.urlopen("%s?%s" %(self.url, params))
        data = response.read()
        
        if _debug > 1:
            print __name__, "rpc call received", data
            
        result = simplejson.loads(data)
        
        try: 
            if 'error' in result: 
                raise ChimpyException(result['error'])
        except TypeError:
            # thrown when results is not iterable (eg bool)    
            pass
        
        return result 
    
    
    def _api_call(self, **params):
        """make an api call"""
        
        assert 'method' in params, \
            'you must specify a method for an api call'
            
            
        # flatten the merge variables
        if 'merge_vars' in params:
            merge_vars = params['merge_vars']
            del params['merge_vars']
            
            for (k,v) in merge_vars.items():
                params['merge_vars[%s]' % k] = v
        
        params['output'] = self.output
        params['apikey'] = self._apikey
        
        return self._rpc(**params)
        
        
    def ping(self):
        return self._api_call(method='ping')
        
    def lists(self):
        return self._api_call(method='lists')
        
    def list_subscribe(self, 
                        id, 
                        email_address, 
                        merge_vars, 
                        email_type='text', 
                        double_optin=True):
        return self._api_call(method='listSubscribe',
                                id=id, 
                                email_address=email_address,
                                merge_vars=merge_vars,
                                email_type=email_type,
                                double_optin=double_optin)
                                
    def list_unsubscribe(self, 
                        id, 
                        email_address, 
                        delete_member=False,  
                        send_goodbye=True,
                        send_notify=True):
        return self._api_call(method='listUnsubscribe',
                                id=id,
                                email_address=email_address,
                                delete_member=delete_member,
                                send_goodbye=send_goodbye,
                                send_notify=send_notify)
                                
    def list_update_member(self, 
                            id, 
                            email_address, 
                            merge_vars, 
                            email_type='', 
                            replace_interests=True):
        return self._api_call(method='listUpdateMember',
                                id=id, 
                                email_address=email_address,
                                merge_vars=merge_vars,
                                email_type=email_type, 
                                replace_interests=replace_interests)

    def list_member_info(self, id, email_address):
        return self._api_call(method='listMemberInfo',
                                id=id, 
                                email_address=email_address)
                                
    def list_members(self, id, status='subscribed'):
        return self._api_call(method='listMembers', id=id, status=status)

    def list_interest_groups(self, id):
        return self._api_call(method='listInterestGroups', id=id)
        
    def list_interest_group_add(self, id, name):
        return self._api_call(method='listInterestGroupAdd', id=id, group_name=name)
    
    def list_interest_group_del(self, id, name):
        return self._api_call(method='listInterestGroupDel', id=id, group_name=name)    


    def list_merge_vars(self, id):
        return self._api_call(method='listMergeVars', id=id)

    def list_merge_var_add(self, id, tag, name, req=False):
        return self._api_call(method='listMergeVarAdd', id=id, tag=tag, name=name, req=req)

    def list_merge_var_del(self, id, tag):
        return self._api_call(method='listMergeVarDel', id=id, tag=tag)

        